﻿
namespace n_LatticeToCode
{
using System;
using System.Drawing;
using c_MyObjectSet;

//点阵取模器
public static class LatticeToCode
{
	static int WidthN;
	static int HeightN;
	static bool isDec;
	
	public const int T_bitmap = 0;
	public const int T_ascii = 128;
	public const int T_part_ascii = 129;
	public const int T_part_chinese = 130;
	
	public const string L_DownRight = "DownRight";
	public const string L_UpRight = "UpRight";
	public const string L_DownLeft = "DownLeft";
	public const string L_UpLeft = "UpLeft";
	public const string L_RightUp = "RightUp";
	public const string L_RightDown = "RightDown";
	public const string L_LeftUp = "LeftUp";
	public const string L_LeftDown = "LeftDown";
	
	public const string L_V1_RightDown = "V1_RightDown";
	public const string L_V1_DownRight = "V1_DownRight";
	
	public static int CharNumber = 94;
	
	//获取位图数组的点阵
	public static bool[][] GetLatticeFromArray( string s, ref int T, ref int CW, ref int H, ref string Mes  )
	{
		if( s.StartsWith( L_DownRight ) ) {
			return GetLatticeFromArray_B( s.Remove( 0, 10 ), ref T, ref CW, ref H, ref Mes );
		}
		else if( s.StartsWith( L_RightDown ) ) {
			return GetLatticeFromArray_A_Old( s.Remove( 0, 10 ), ref T, ref CW, ref H, ref Mes );
		}
		else if( s.StartsWith( L_V1_RightDown ) ) {
			return GetLatticeFromArray_A( s.Remove( 0, 13 ), ref T, ref CW, ref H, ref Mes );
		}
		else if( s.StartsWith( L_V1_DownRight ) ) {
			return GetLatticeFromArray_B( s.Remove( 0, 13 ), ref T, ref CW, ref H, ref Mes );
		}
		else {
			return GetLatticeFromArray_A( s, ref T, ref CW, ref H, ref Mes );
		}
	}
	
	//获取位图数组的点阵
	public static bool[][] GetLatticeFromArray_A_Old( string s, ref int T, ref int CW, ref int H, ref string Mes )
	{
		string[] cut = s.Replace( '\n', ' ' ).Replace( '\t', ' ' ).Trim( ',' ).Split( ',' );
		for( int i = 0; i < cut.Length; ++i ) {
			cut[ i ] = cut[ i ].Trim( ' ' );
		}
		
		T = int.Parse( cut[ 0 ] );
		CW = int.Parse( cut[ 1 ] );
		int Wl = int.Parse( cut[ 2 ] );
		int Wh = int.Parse( cut[ 3 ] );
		H = int.Parse( cut[ 4 ] );
		
		int d0 = int.Parse( cut[ 5 ] );
		int d1 = int.Parse( cut[ 6 ] );
		int d2 = int.Parse( cut[ 7 ] );
		int d3 = int.Parse( cut[ 8 ] );
		
		int W = Wh * 256 + Wl;
		
		int k = 9;
		if( T == T_part_ascii || T == T_part_chinese ) {
			
			int CharNumber = int.Parse( cut[9] );
			k = 9 + 1 + CharNumber;
			Mes = "";
			for( int i = 0; i < CharNumber; ++i ) {
				int cc  = int.Parse(cut[ 10 + i ]);
				if( cc > 127 ) {
					char c = System.Text.Encoding.GetEncoding("GBK").GetChars( new byte[] {(byte)cc, byte.Parse(cut[ 10 + i + 1 ]) } )[0];
					Mes += c.ToString();
					i++;
				}
				else {
					Mes += ((char)cc).ToString();
				}
			}
		}
		
		bool[][] PointSet = new bool[ W ][];
		for( int x = 0; x < W; ++x ) {
			PointSet[ x ] = new bool[ H ];
		}
		
		for( int y = 0; y < H; y += 8 ) {
			for( int x = 0; x < W; ++x ) {
				
				int D = 0;
				if( cut[ k ].StartsWith( "0x" ) ) {
					D = int.Parse( cut[ k ].Remove( 0, 2 ), System.Globalization.NumberStyles.HexNumber );
				}
				else {
					D = int.Parse( cut[ k ] );
				}
				if( y + 0 < H ) PointSet[ x ][ y + 0 ] = (D & 0x01) != 0;
				if( y + 1 < H ) PointSet[ x ][ y + 1 ] = (D & 0x02) != 0;
				if( y + 2 < H ) PointSet[ x ][ y + 2 ] = (D & 0x04) != 0;
				if( y + 3 < H ) PointSet[ x ][ y + 3 ] = (D & 0x08) != 0;
				if( y + 4 < H ) PointSet[ x ][ y + 4 ] = (D & 0x10) != 0;
				if( y + 5 < H ) PointSet[ x ][ y + 5 ] = (D & 0x20) != 0;
				if( y + 6 < H ) PointSet[ x ][ y + 6 ] = (D & 0x40) != 0;
				if( y + 7 < H ) PointSet[ x ][ y + 7 ] = (D & 0x80) != 0;
				++k;
			}
		}
		return PointSet;
	}
	
	//获取位图数组的点阵
	public static bool[][] GetLatticeFromArray_A( string s, ref int T, ref int CW, ref int H, ref string Mes )
	{
		string[] cut = s.Replace( '\n', ' ' ).Replace( '\t', ' ' ).Trim( ',' ).Split( ',' );
		for( int i = 0; i < cut.Length; ++i ) {
			cut[ i ] = cut[ i ].Trim( ' ' );
		}
		
		T = int.Parse( cut[ 0 ] );
		CW = int.Parse( cut[ 1 ] );
		int Wl = int.Parse( cut[ 2 ] );
		int Wh = int.Parse( cut[ 3 ] );
		H = int.Parse( cut[ 4 ] );
		
		int d0 = int.Parse( cut[ 5 ] );
		int d1 = int.Parse( cut[ 6 ] );
		int d2 = int.Parse( cut[ 7 ] );
		int d3 = int.Parse( cut[ 8 ] );
		
		int W = Wh * 256 + Wl;
		
		int k = 9;
		if( T == T_part_ascii || T == T_part_chinese ) {
			
			int CharNumber = int.Parse( cut[9] );
			k = 9 + 1 + CharNumber;
			Mes = "";
			for( int i = 0; i < CharNumber; ++i ) {
				int cc  = int.Parse(cut[ 10 + i ]);
				if( cc > 127 ) {
					char c = System.Text.Encoding.GetEncoding("GBK").GetChars( new byte[] {(byte)cc, byte.Parse(cut[ 10 + i + 1 ]) } )[0];
					Mes += c.ToString();
					i++;
				}
				else {
					Mes += ((char)cc).ToString();
				}
			}
		}
		
		bool[][] PointSet = new bool[ W ][];
		for( int x = 0; x < W; ++x ) {
			PointSet[ x ] = new bool[ H ];
		}
		
		for( int y = 0; y < H; y += 8 ) {
			for( int x = 0; x < W; ++x ) {
				
				int D = 0;
				if( cut[ k ].StartsWith( "0x" ) ) {
					D = int.Parse( cut[ k ].Remove( 0, 2 ), System.Globalization.NumberStyles.HexNumber );
				}
				else {
					D = int.Parse( cut[ k ] );
				}
				if( y + 0 < H ) PointSet[ x ][ y + 0 ] = (D & 0x01) != 0;
				if( y + 1 < H ) PointSet[ x ][ y + 1 ] = (D & 0x02) != 0;
				if( y + 2 < H ) PointSet[ x ][ y + 2 ] = (D & 0x04) != 0;
				if( y + 3 < H ) PointSet[ x ][ y + 3 ] = (D & 0x08) != 0;
				if( y + 4 < H ) PointSet[ x ][ y + 4 ] = (D & 0x10) != 0;
				if( y + 5 < H ) PointSet[ x ][ y + 5 ] = (D & 0x20) != 0;
				if( y + 6 < H ) PointSet[ x ][ y + 6 ] = (D & 0x40) != 0;
				if( y + 7 < H ) PointSet[ x ][ y + 7 ] = (D & 0x80) != 0;
				++k;
			}
		}
		return PointSet;
	}
	
	//获取位图数组的点阵
	public static bool[][] GetLatticeFromArray_B( string s, ref int T, ref int CW, ref int H, ref string Mes )
	{
		string[] cut = s.Replace( '\n', ' ' ).Replace( '\t', ' ' ).Trim( ',' ).Split( ',' );
		for( int i = 0; i < cut.Length; ++i ) {
			cut[ i ] = cut[ i ].Trim( ' ' );
		}
		T = int.Parse( cut[ 0 ] );
		CW = int.Parse( cut[ 1 ] );
		
		int Wl = int.Parse( cut[ 2 ] );
		int Wh = int.Parse( cut[ 3 ] );
		H = int.Parse( cut[ 4 ] );
		
		int d0 = int.Parse( cut[ 5 ] );
		int d1 = int.Parse( cut[ 6 ] );
		int d2 = int.Parse( cut[ 7 ] );
		int d3 = int.Parse( cut[ 8 ] );
		
		int W = Wh * 256 + Wl;
		
		bool[][] PointSet = new bool[ W ][];
		for( int x = 0; x < W; ++x ) {
			PointSet[ x ] = new bool[ H ];
		}
		int k = 2;
		for( int x = 0; x < W; x += 8 ) {
			for( int y = 0; y < H; ++y ) {
				
				int D = 0;
				if( cut[ k ].StartsWith( "0x" ) ) {
					D = int.Parse( cut[ k ].Remove( 0, 2 ), System.Globalization.NumberStyles.HexNumber );
				}
				else {
					D = int.Parse( cut[ k ] );
				}
				PointSet[ x + 7 ][ y ] = (D & 0x01) != 0;
				PointSet[ x + 6 ][ y ] = (D & 0x02) != 0;
				PointSet[ x + 5 ][ y ] = (D & 0x04) != 0;
				PointSet[ x + 4 ][ y ] = (D & 0x08) != 0;
				PointSet[ x + 3 ][ y ] = (D & 0x10) != 0;
				PointSet[ x + 2 ][ y ] = (D & 0x20) != 0;
				PointSet[ x + 1 ][ y ] = (D & 0x40) != 0;
				PointSet[ x + 0 ][ y ] = (D & 0x80) != 0;
				++k;
			}
		}
		return PointSet;
	}
	
	//获取文字的点阵
	public static bool[][] GetLatticeFont( string s, Font TextFont, bool IsDec, int tW, int tH, int CW, int CH )
	{
		isDec = IsDec;
		WidthN = CW * CharNumber;
		HeightN = CH;
		
		Bitmap pic = new Bitmap( WidthN, HeightN );
		Graphics g = Graphics.FromImage( pic );
		g.Clear( Color.White );
		DrawChar( s, TextFont, g, tW, tH, CW, CH );
		
		bool[][] PointSet = new bool[ WidthN ][];
		for( int x = 0; x < WidthN; ++x ) {
			PointSet[ x ] = new bool[ HeightN ];
			for( int y = 0; y < HeightN; ++y ) {
				if( pic.GetPixel( x, y ).G < 100 ) {
					PointSet[ x ][ y ] = true;
				}
			}
		}
		return PointSet;
	}
	
	//获取文字的点阵
	public static bool[][] GetLatticeBitmap( string s, Font TextFont, bool IsDec, int tW, int tH )
	{
		isDec = IsDec;
		
		Size RSize = GetSizeWithDraw( s, TextFont, null, tW, tH );
		WidthN = RSize.Width;
		int h = RSize.Height;
		HeightN = h / 8;
		if( h % 8 != 0 ) {
			HeightN += 1;
		}
		HeightN *= 8;
		
		Bitmap pic = new Bitmap( WidthN, HeightN );
		Graphics g = Graphics.FromImage( pic );
		g.Clear( Color.White );
		GetSizeWithDraw( s, TextFont, g, tW, tH );
		
		bool[][] PointSet = new bool[ WidthN ][];
		for( int x = 0; x < WidthN; ++x ) {
			PointSet[ x ] = new bool[ HeightN ];
			for( int y = 0; y < HeightN; ++y ) {
				if( pic.GetPixel( x, y ).G < 100 ) {
					PointSet[ x ][ y ] = true;
				}
			}
		}
		return PointSet;
	}
	
	//获取字符串的尺寸(可设置是否带有绘图操作, 一般需要调用两次)
	static void DrawChar( string s, Font TextFont, Graphics g, int tW, int tH, int CW, int CH )
	{
		int SX = 0;
		int SY = 0;
		
		for( int i = 0; i < s.Length; i++ ) {
			SizeF csf = g.MeasureString( s[i].ToString(), TextFont );
			int ww = (int)csf.Width;
			int hh = (int)csf.Height;
			g.DrawString( s[i].ToString(), TextFont, Brushes.Black, SX + tW, SY + tH );
			SX += CW;
		}
	}
	
	//获取字符串的尺寸(可设置是否带有绘图操作, 一般需要调用两次)
	static Size GetSizeWithDraw( string s, Font TextFont, Graphics g, int tW, int tH )
	{
		int MaxWidth = 0;
		int MaxHeight = 0;
		
		int SX = 0;
		int SY = 0;
		Bitmap pic = new Bitmap( 1, 1 );
		Graphics tg = Graphics.FromImage( pic );
		for( int i = 0; i < s.Length; i++ ) {
			SizeF csf = tg.MeasureString( s[i].ToString(), TextFont );
			int ww = (int)csf.Width;
			int hh = (int)csf.Height;
			if( s[i] == '\n' ) {
				SY += hh + tH;
				SX = 0;
				continue;
			}
			if( g != null ) {
				g.DrawString( s[i].ToString(), TextFont, Brushes.Black, SX, SY );
			}
			SX += ww;
			if( MaxWidth < SX ) {
				MaxWidth = SX;
			}
			SX += tW;
			
			if( MaxHeight < SY + hh ) {
				MaxHeight = SY + hh;
			}
		}
		return new Size( MaxWidth, MaxHeight );
	}
	
	//获取一个点阵的编码
	public static string GetCode( bool[][] LatticeList, string LatticeType, int UserType, int CharWidth, string Mes )
	{
		int W = LatticeList.Length;
		int H = LatticeList[ 0 ].Length;
		
		SetSize( W, H );
		int WidthDiv = WidthN;
		int HeightDiv = HeightN;
		
		string ss = "";
		if( ( UserType == T_part_ascii || UserType == T_part_chinese ) && Mes != null ) {
			
			int Length = Mes.Length;
			for( int i = 0; i < Mes.Length; ++i ) {
				
				if( (int)Mes[i] > 255 ) {
					byte[] gbk = System.Text.Encoding.GetEncoding("GBK").GetBytes( (Mes[i]).ToString() );
					ss += gbk[0] + ",";
					ss += gbk[1] + ",";
					Length += 1;
				}
				else {
					ss += (int)Mes[i] + ",";
				}
			}
			ss = Length + "," + ss;
		}
		ss += "\n";
		
		string r = UserType + "," + CharWidth + ",";
		if( LatticeType == L_DownRight ) {
			r += HeightN + "," + WidthDiv + ",0,0,0,0," + ss + DownRight( LatticeList );
		}
		else if( LatticeType == L_UpRight ) {
			r += HeightN + "," + WidthDiv + ",0,0,0,0," + ss + UpRight( LatticeList );
		}
		else if( LatticeType == L_DownLeft ) {
			r += HeightN + "," + WidthDiv + ",0,0,0,0," + ss + DownLeft( LatticeList );
		}
		else if( LatticeType == L_UpLeft ) {
			r += HeightN + "," + WidthDiv + ",0,0,0,0," + ss + UpLeft( LatticeList );
		}
		else if( LatticeType == L_RightUp ) {
			r += WidthN + "," + HeightDiv + ",0,0,0,0," + ss + RightUp( LatticeList );
		}
		else if( LatticeType == L_RightDown ) {
			r += (WidthN%256) + "," + (WidthN/256) + "," + HeightDiv + ",0,0,0,0," + ss + RightDown( LatticeList );
		}
		else if( LatticeType == L_LeftUp ) {
			r += WidthN + "," + HeightDiv + ",0,0,0,0," + ss + LeftUp( LatticeList );
		}
		else if( LatticeType == L_LeftDown ) {
			r += WidthN + "," + HeightDiv + ",0,0,0,0," + ss + LeftDown( LatticeList );
		}
		//else if( LatticeType == v1_DownRight ) {
		//	r = WidthN + "," + HeightDiv + ",\n" + V1_DownRight( LatticeList );
		//}
		else if( LatticeType == L_V1_RightDown ) {
			r += (WidthN%256) + "," + (WidthN/256) + "," + HeightDiv + ",0,0,0,0," + ss + RightDown( LatticeList );
		}
		else if( LatticeType == L_V1_DownRight ) {
			r += (WidthN%256) + "," + (WidthN/256) + "," + HeightDiv + ",0,0,0,0," + ss + DownRight( LatticeList );
		}
		else {
			return null;
		}
		return LatticeType + "," + r.Trim( '\n' );
	}
	
	//设置点阵大小
	static void SetSize( int W, int H )
	{
		WidthN = W;
		HeightN = H;
	}
	
	//方式一 每次从上到下, 逐渐从左到右
	static string DownRight( bool[][] LatticeList )
	{
		string R = "";
		for( int x = 0; x < WidthN; x += 8 ) {
			for( int y = 0; y < HeightN; ++y ) {
				byte D = 0;
				for( int i = 0; i < 8; ++i ) {
					D <<= 1;
					if( x + i < WidthN && LatticeList[ x + i ][ y ] ) {
						D |= 0x01;
					}
				}
				if( isDec ) {
					R += D + ",";
				}
				else {
					R += "0x" + D.ToString( "X" ).PadLeft( 2, '0' ) + ",";
				}
			}
			R += "\n";
		}
		return R;
	}
	
	//方式二 每次从下到上, 逐渐从左到右
	static string UpRight( bool[][] LatticeList )
	{
		string R = "";
		for( int x = 0; x < WidthN; x += 8 ) {
			for( int y = HeightN - 1; y >= 0; --y ) {
				byte D = 0;
				for( int i = 0; i < 8; ++i ) {
					D >>= 1;
					if( x + i < WidthN && LatticeList[ x + i ][ y ] ) {
						D |= 0x80;
					}
				}
				if( isDec ) {
					R += D + ",";
				}
				else {
					R += "0x" + D.ToString( "X" ).PadLeft( 2, '0' ) + ",";
				}
			}
			R += "\n";
		}
		return R;
	}
	
	//方式三 每次从上到下, 逐渐从右到左
	static string DownLeft( bool[][] LatticeList )
	{
		string R = "";
		for( int x = WidthN - 1; x >= 0; x -= 8 ) {
			for( int y = 0; y < HeightN; ++y ) {
				byte D = 0;
				for( int i = 0; i < 8; ++i ) {
					D >>= 1;
					if( x - i >= 0 && LatticeList[ x - i ][ y ] ) {
						D |= 0x80;
					}
				}
				if( isDec ) {
					R += D + ",";
				}
				else {
					R += "0x" + D.ToString( "X" ).PadLeft( 2, '0' ) + ",";
				}
			}
			R += "\n";
		}
		return R;
	}
	
	//方式四 每次从下到上, 逐渐从右到左
	static string UpLeft( bool[][] LatticeList )
	{
		string R = "";
		for( int x = WidthN - 1; x >= 0; x -= 8 ) {
			for( int y = HeightN - 1; y >= 0; --y ) {
				byte D = 0;
				for( int i = 0; i < 8; ++i ) {
					D >>= 1;
					if( x - i >= 0 && LatticeList[ x - i ][ y ] ) {
						D |= 0x80;
					}
				}
				if( isDec ) {
					R += D + ",";
				}
				else {
					R += "0x" + D.ToString( "X" ).PadLeft( 2, '0' ) + ",";
				}
			}
			R += "\n";
		}
		return R;
	}
	
	//方式五 每次从左到右, 逐渐从上到下
	static string RightDown( bool[][] LatticeList )
	{
		string R = "";
		for( int y = 0; y < HeightN; y += 8 ) {
			for( int x = 0; x < WidthN; ++x ) {
				byte D = 0;
				for( int i = 0; i < 8; ++i ) {
					
					D >>= 1;
					if( y + i < HeightN && LatticeList[ x ][ y + i ] ) {
						D |= 0x80;
					}
				}
				if( isDec ) {
					R += D + ",";
				}
				else {
					R += "0x" + D.ToString( "X" ).PadLeft( 2, '0' ) + ",";
				}
			}
			R += "\n";
		}
		return R;
	}
	
	//方式六 每次从左到右, 逐渐从下到上
	static string RightUp( bool[][] LatticeList )
	{
		string R = "";
		for( int y = HeightN - 1; y >= 0; y -= 8 ) {
			for( int x = 0; x < WidthN; ++x ) {
				byte D = 0;
				for( int i = 0; i < 8; ++i ) {
					D >>= 1;
					if( y - i >= 0 && LatticeList[ x ][ y - i ] ) {
						D |= 0x80;
					}
				}
				if( isDec ) {
					R += D + ",";
				}
				else {
					R += "0x" + D.ToString( "X" ).PadLeft( 2, '0' ) + ",";
				}
			}
			R += "\n";
		}
		return R;
	}
	
	//方式七 每次从右到左, 逐渐从上到下
	static string LeftDown( bool[][] LatticeList )
	{
		string R = "";
		for( int y = 0; y < HeightN; y += 8 ) {
			for( int x = WidthN - 1; x >= 0; --x ) {
				byte D = 0;
				for( int i = 0; i < 8; ++i ) {
					D >>= 1;
					if( y + i < HeightN && LatticeList[ x ][ y + i ] ) {
						D |= 0x80;
					}
				}
				if( isDec ) {
					R += D + ",";
				}
				else {
					R += "0x" + D.ToString( "X" ).PadLeft( 2, '0' ) + ",";
				}
			}
			R += "\n";
		}
		return R;
	}
	
	//方式八 每次从右到左, 逐渐从下到上
	static string LeftUp( bool[][] LatticeList )
	{
		string R = "";
		for( int y = HeightN - 1; y >= 0; y -= 8 ) {
			for( int x = WidthN - 1; x >= 0; --x ) {
				byte D = 0;
				for( int i = 0; i < 8; ++i ) {
					D >>= 1;
					if( y - i >= 0 && LatticeList[ x ][ y - i ] ) {
						D |= 0x80;
					}
				}
				if( isDec ) {
					R += D + ",";
				}
				else {
					R += "0x" + D.ToString( "X" ).PadLeft( 2, '0' ) + ",";
				}
			}
			R += "\n";
		}
		return R;
	}
}
}

